package com.example.mq.mqserver.core;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/*
* 这个类表示要传递的信息
* 还有就是 Message 是需要可以在网络上传输，并且也需要能写入文件的
* 此时就需要针对 Message 进行序列化和反序列化
* 此处使用 标准库 自带的序列化和反序列化 操作 而不是使用json方式，
* json本质上是文本格式（里面存储的也是文本类型的数据）
* 而此处的 Message，里面存储的是二进制数据
* */
public class Message implements Serializable {

    //这两个属性是Message 最核心的部分
    public BasicProperties basicProperties = new BasicProperties();
    private byte[] body;

    //以下的属性则是辅助用的属性（Message后续会存储到文件中（如果持久化的话））
    //一个文件会存储很多消息，如果要找到一个消息就需要记录这个消息在文件中存储的位置
    //然后就使用以字节为单位的偏移量来表示 使用前闭后开表示[offsetBeg, offsetEnd)
    //这俩属性并不需要被序列化保存到文件中，此处的消息一旦被写入文件之后，所在的位置就固定了，并不需要单独存储
    //这俩属性存在的目的主要就是为了让内存中的 Message 对象能够快速找到对应的硬盘上的 Message 的位置
    private transient long offsetBeg = 0;//消息数据距离文件开头的位置
    private transient long offsetEnd = 0;//消息数据距离文件结尾的位置
    //使用isValid属性表示该消息在文件中是否是有效的消息（针对文件中的消息如果删除就使用逻辑删除）
    //0x1 表示有效，0x0表示无效
    private byte isValid = 0x1;

    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    //创建一个工厂方法，让工厂方法帮我们封装以下创建 Message 对象的过程
    //这个方法中创建的 Message 对象，会自动生成一个唯一的 MessageId
    //万一 routingKey 和 basicProperties 里的 routingKey冲突，以外边的为主
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if (basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        //此处的 MessageId 以 M- 作为前缀（后边有很多不同含义的id都是用UUID来生成的，所以加一个前缀好区分）
        message.setMessageId("M-" + UUID.randomUUID());
        message.setRoutingKey(routingKey);
        message.body = body;
        //此处是把body 和 basicProperties 先设置好，他俩是 Message 的核心内容
        //而offsetBeg，offsetEnd，isValid 是消息持久化的时候才会用到，在把消息写入文件的时候再进行设定
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }
    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }
    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }
    public void setDeliverMode(int deliverMode) {
        basicProperties.setDeliverMode(deliverMode);
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isValid=" + isValid +
                '}';
    }
}
